package net.ikenway.springboot.demo.Config;

import net.ikenway.springboot.demo.Model.Dto.*;
import net.ikenway.springboot.demo.Model.Entity.*;
import org.modelmapper.Conditions;
import org.modelmapper.ModelMapper;
import org.modelmapper.PropertyMap;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author MasterKenway <zk@ikenway.net>
 * @Description
 * @date Created Date 12/10/2020
 */
@Configuration
public class ModelMapperConfig {
    @Bean
    public ModelMapper loadMapper() {
        ModelMapper mapper = new ModelMapper();
        PropertyMap<User, UserDto> userMap = new PropertyMap<User, UserDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getUsername(), destination.getUsername());
                when(Conditions.isNotNull()).map(source.getName(), destination.getName());
                when(Conditions.isNotNull()).map(source.getAvatar(), destination.getAvatar());
                when(Conditions.isNotNull()).map(source.getIdentity(), destination.getIdentity());
                when(Conditions.isNotNull()).map(source.getEnabled(), destination.getEnable());
            }
        };
        mapper.addMappings(userMap);

        PropertyMap<Order, OrderDto> orderMap = new PropertyMap<Order, OrderDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getOrderId(), destination.getOrderId());
                when(Conditions.isNotNull()).map(source.getTotalPrice(), destination.getTotalPrice());
                when(Conditions.isNotNull()).map(source.getCreateTime(), destination.getCreateTime());
                when(Conditions.isNotNull()).map(source.getPurchaseTime(), destination.getPurchaseTime());
                when(Conditions.isNotNull()).map(source.getType(), destination.getType());
                when(Conditions.isNotNull()).map(source.getStatus(), destination.getStatus());
//                when(Conditions.isNotNull()).map(source.getOrderSubs(), destination.getOrderSubDtos());
                when(Conditions.isNotNull()).map(source.getAddress().getAddressId(), destination.getAddressId());
                when(Conditions.isNotNull()).map(source.getUser().getUserId(), destination.getUserId());
            }
        };
        mapper.addMappings(orderMap);

        PropertyMap<OrderSub, OrderSubDto> orderSubMap = new PropertyMap<OrderSub, OrderSubDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getProduct().getProductId(), destination.getProductId());
                when(Conditions.isNotNull()).map(source.getProduct().getProductName(), destination.getProductName());
                when(Conditions.isNotNull()).map(source.getDisCount(), destination.getDisCount());
                when(Conditions.isNotNull()).map(source.getActualPrice(), destination.getActualPrice());
                when(Conditions.isNotNull()).map(source.getAdditions(), destination.getAdditions());
                when(Conditions.isNotNull()).map(source.getScale(), destination.getScale());
            }
        };
        mapper.addMappings(orderSubMap);

        PropertyMap<Product, ProductDto> productMap = new PropertyMap<Product, ProductDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getProductId(), destination.getProductId());
                when(Conditions.isNotNull()).map(source.getProductName(), destination.getProductName());
                when(Conditions.isNotNull()).map(source.getProductSort().getSortName(), destination.getSortName());
                when(Conditions.isNotNull()).map(source.getProductSort().getSortId(), destination.getSortId());
                when(Conditions.isNotNull()).map(source.getMediumPrice(), destination.getMediumPrice());
                when(Conditions.isNotNull()).map(source.getLargePrice(), destination.getLargePrice());
                when(Conditions.isNotNull()).map(source.getPreview(), destination.getPreview());
                when(Conditions.isNotNull()).map(source.getSellCounter(), destination.getSellCounter());
                when(Conditions.isNotNull()).map(source.getDeleted(), destination.getDeleted());
            }
        };
        mapper.addMappings(productMap);

        PropertyMap<ProductSort, ProductSortDto> productSortMap = new PropertyMap<ProductSort, ProductSortDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getSortId(), destination.getSortId());
                when(Conditions.isNotNull()).map(source.getSortName(), destination.getSortName());
                when(Conditions.isNotNull()).map(source.getDisplayOrder(), destination.getDisplayOrder());
                when(Conditions.isNotNull()).map(source.getEnable(), destination.getEnable());
                when(Conditions.isNotNull()).map(source.getProducts(), destination.getProducts());
            }
        };
        mapper.addMappings(productSortMap);

        PropertyMap<Address, AddressDto> addressDtoPropertyMap = new PropertyMap<Address, AddressDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getAddressId(), destination.getAddressId());
                when(Conditions.isNotNull()).map(source.getContactName(), destination.getContactName());
                when(Conditions.isNotNull()).map(source.getPhoneNumber(), destination.getPhoneNumber());
                when(Conditions.isNotNull()).map(source.getProvince(), destination.getProvince());
                when(Conditions.isNotNull()).map(source.getCity(), destination.getCity());
                when(Conditions.isNotNull()).map(source.getStreet(), destination.getStreet());
                when(Conditions.isNotNull()).map(source.getRemark(), destination.getRemark());
            }
        };
        mapper.addMappings(addressDtoPropertyMap);

        PropertyMap<Activity, ActivityDto> activityActivityDtoPropertyMap = new PropertyMap<Activity, ActivityDto>() {
            @Override
            protected void configure() {
                when(Conditions.isNotNull()).map(source.getActId(), destination.getActId());
                when(Conditions.isNotNull()).map(source.getActName(), destination.getActName());
                when(Conditions.isNotNull()).map(source.getImageUrl(), destination.getImageUrl());
                when(Conditions.isNotNull()).map(source.getDisCount(), destination.getDisCount());
                when(Conditions.isNotNull()).map(source.getProducts(), destination.getProducts());
                when(Conditions.isNotNull()).map(source.getEnable(), destination.getEnable());
                when(Conditions.isNotNull()).map(source.getDisplayOrder(), destination.getDisplayOrder());
            }
        };
        mapper.addMappings(activityActivityDtoPropertyMap);

        mapper.getConfiguration()
                .setFieldMatchingEnabled(true)
                .setMatchingStrategy(MatchingStrategies.STRICT)
                .setSkipNullEnabled(true);
        return mapper;
    }
}
